package com.ccl.keyassistant.db;
/*
 *项目名     keyassistant
 *包名       com.ccl.keyassistant.db
 *文件名     DBDataHelper
 *创建者     ccl
 *创建时间   2019-03-16 15:05
 *注解       数据助手类，三层架构，应用层调用DBDataHelper,DBDataHelper调用DBHelper完成真正的数据存储，仿照慕课网课程实现
 */

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;

import com.ccl.keyassistant.entity.BaseModel;
import com.ccl.keyassistant.utils.L;
import com.ccl.keyassistant.utils.StaticClass;

import net.sqlcipher.database.SQLiteDatabase;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;

public final class DBDataHelper {
    private static DBHelper helper = null;
    private static DBDataHelper dbDataHelper = null;

    private static final String SELECT = " select ";
    private static final String FROM = " from ";
    private static final String WHERE = " where ";
    private static final String ORDER_BY = " order by ";

    private DBDataHelper(Context context) {
        helper = DBHelper.getInstance(context);
    }


    public static DBDataHelper getInstance(Context context) {
        if (dbDataHelper == null) {
            dbDataHelper = new DBDataHelper(context);
        }
        return dbDataHelper;
    }

    /**
     * 单条件查询给定列
     *
     * @param table
     * @param columns       查询的列
     * @param selection     查询条件
     * @param selectionArgs 条件对应的值
     * @param orderBy       排序
     * @param cls           要转换成的对象类型
     * @return
     */
    public ArrayList<BaseModel> select(String table, String columns, String selection,
                                       String selectionArgs, String orderBy, Class<?> cls) {
        SQLiteDatabase database = null;
        ArrayList<BaseModel> modelList = new ArrayList<BaseModel>();
        try {
            database = helper.getReadableDatabase(StaticClass.MMSM);
            L.i("mmsm:"+StaticClass.MMSM);
            String sql = SELECT;
            sql += columns == null ? " * " : columns;

            if (selection != null && selectionArgs != null) {
                sql += FROM + table + WHERE + selection + " = " + selectionArgs;
            } else {
                sql += FROM + table;
            }
            if (orderBy != null) {
                sql += ORDER_BY + orderBy;
            }
            sql += " ; ";

            Cursor cursor = database.rawQuery(sql, null);
            L.i("select column:" + sql);
            changeToList(cursor, modelList, cls);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            helper.closeDataBase(database);
        }
        return modelList;
    }

    /**
     * 查找数据表，多条件查询，查询所有列
     *
     * @param table         要操作的表
     * @param selection     匹配条件，例如"id>?and name <>?",不需要可以设为null
     * @param selectionArgs 与selection相对应，里面的字符串将替换selection里的"?",
     *                      构成完整的匹配条件，例如{"6","jack"}
     * @param orderby       排序参数
     * @param moduleClass   要转化成的模型类Class,例如要转成WebPage则传入WebPage.class
     * @return 数据模型集合, 集合是的对象类型为moduleClass
     */
    public ArrayList<BaseModel> select(final String table, final String[] columns,final String selection, final String[] selectionArgs,
                                       final String orderby, final Class<?> moduleClass) {
        SQLiteDatabase database = null;
        Cursor cursor = null;
        ArrayList<BaseModel> moduleList = new ArrayList<BaseModel>();
        synchronized (helper) {
            try {
                database = helper.getReadableDatabase(StaticClass.MMSM);
                L.i("mmsm:"+StaticClass.MMSM);
                // 查询数据
                cursor = database.query(table, columns, selection, selectionArgs, null, null, orderby, null);
                L.i(cursor.getCount() + " cursor count");
                // 将结果转换成为数据模型
                changeToList(cursor, moduleList, moduleClass);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                helper.closeDataBase(database);
            }
            return moduleList;
        }
    }


    /**
     * 向表中插入单个数据
     *
     * @param table 要插入的表
     * @param model 要插入的数据对象
     * @return
     */
    public long insert(String table, BaseModel model) {
        synchronized (helper) {
            ContentValues values = moduleToContentValues(model);
            long insert = helper.insert(table, null, values);
            return insert;
        }

    }


    /**
     * 向表中插入多个数据
     *
     * @param table
     * @param modelList
     * @return
     */
    public boolean insert(String table, ArrayList<BaseModel> modelList) {
        ArrayList<ContentValues> valuesList = moduleToContentValues(modelList);
        return helper.insert(table, null, valuesList);
    }


    /**
     * 删除数据
     *
     * @param table
     * @param whereCaluse 删除条件 name=?
     * @param whereArgs   条件对应的值 ?的值
     * @return
     */
    public int delete(String table, String whereCaluse, String[] whereArgs) {
        synchronized (helper) {
            return helper.delete(table, whereCaluse, whereArgs);
        }
    }


    /**
     * 更新数据
     *
     * @param table 表
     * @param whereCaluse 更新条件 name=?
     * @param whereArgs 对应的值 ?的值
     * @param model 要更新的数据
     * @return
     */
    public int update(String table, String whereCaluse, String[] whereArgs, BaseModel model) {
        synchronized (helper) {
            ContentValues values = moduleToContentValues(model);
            return helper.update(table, values, whereCaluse, whereArgs);
    }
    }


    private ArrayList<ContentValues> moduleToContentValues(ArrayList<BaseModel> modelList) {
        ArrayList<ContentValues> list = new ArrayList<ContentValues>();
        for (BaseModel model : modelList) {
            ContentValues values = moduleToContentValues(model);
            list.add(values);
        }
        return list;
    }

    /**
     * 将实体类型转成数据库可以直接存储的ContentValues
     *
     * @param model 源Module
     * @return ContentValues
     * @author shenghua.lin
     */
    private ContentValues moduleToContentValues(BaseModel model) {
        ContentValues values = new ContentValues();
        Field[] fields = model.getClass().getDeclaredFields();
        String fieldName;
        String fieldValue;
        int fieldInteger = -1;
        try {
            for (Field field : fields) {
                fieldName = field.getName();
                if (field.get(model) instanceof String) {
                    fieldValue = (String) field.get(model);
                    if (fieldValue != null) {
                        values.put(fieldName, fieldValue);
                    } else {
                        values.put(fieldName, "");
                    }
                } else if (field.get(model) instanceof Integer) {
                    fieldInteger = (Integer) field.get(model);
                    if (fieldInteger != -1) {
                        values.put(fieldName, fieldInteger);
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return values;

    }


    private void changeToList(Cursor cursor, ArrayList<BaseModel> modelList, Class<?> modelClass) {
        //获得行数
        int count = cursor.getCount();
        BaseModel model;
        cursor.moveToFirst();
        try {
            for (int i = 0; i < count; i++) {
                // 转化为moduleClass类的一个实例
                model = changeToModel(cursor, modelClass);
                modelList.add(model);
                cursor.moveToNext();
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } finally {
            cursor.close();
        }

    }

    /**
     * 将游标集合的某一行数据装换成一个具体的对象
     *
     * @param cursor     游标集合的某一行数据
     * @param modelClass 要转换的具体对象
     * @return
     */
    private BaseModel changeToModel(Cursor cursor, Class<?> modelClass) throws
            IllegalAccessException, InstantiationException, NoSuchFieldException {
        synchronized (helper) {
            // 取出所有的列名
            String[] columnNames = cursor.getColumnNames();
            int length = columnNames.length;
            Field field;
            String fieldValue;
            BaseModel model = (BaseModel) modelClass.newInstance();
            // 遍历有列
            for (int i = 0; i < length; i++) {
                field = modelClass.getField(columnNames[i]);
                // 根据列名找到相对应 的字段
                fieldValue = cursor.getString(i);
                if (fieldValue != null) {
                    field.set(model, fieldValue);
                }
            }
            return model;
        }
    }


}
